In a computing environment, a microprocessor typically interacts with other components of the computing device. These interactions, which also may be referred to as transactions or operations, are typically performed either synchronously or asynchronously. In a synchronous interaction, a microprocessor will send a message to another component and suspend processing until a reply is received, whereas in an asynchronous interaction, the microprocessor will send a message to another component and continue processing other instructions without first receiving a reply. For example, in a synchronous transaction, a thread, i.e., a sequence of instructions executing in a processor to complete a task, may request an item of data from memory and suspend further instruction processing until that item is received. However, if that item of data is not immediately needed for further processing of instructions, the data can be requested asynchronously and processing can continue without first receiving the data.
Historically, general-purpose microprocessors have provided an ad-hoc collection of mechanisms to perform operations synchronously and asynchronously. Typically, each particular operation was hard-coded to be executed either synchronously or asynchronously. Many synchronous and asynchronous operations were implicit, and thus not visible to or controllable by software. For example, a processor would synchronously fetch data or instructions from memory, and force an executing thread to stall until a requested datum or instruction arrived. As another example, a processor's data cache would asynchronously flush modified data back to memory without the executing thread necessarily being aware of the cache flush operation. Such microprocessors do not provide generic mechanisms for initiating synchronous and asynchronous operations (possibly concurrent with one another), and managing their replies separately.